1 // Written in the D programming language 2 3 // NOTE: When working on this module, be sure to run tests with -debug=std_socket 4 // E.g.: dmd -version=StdUnittest -debug=std_socket -unittest -main -run socket 5 // This will enable some tests which are too slow or flaky to run as part of CI. 6 7 /* 8 Copyright (C) 2004-2011 Christopher E. Miller 9 10 socket.d 1.4 11 Jan 2011 12 13 Thanks to Benjamin Herr for his assistance. 14 */ 15 16 /** 17 * Socket primitives. 18 * Example: See $(SAMPLESRC listener.d) and $(SAMPLESRC htmlget.d) 19 * License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0). 20 * Authors: Christopher E. Miller, $(HTTP klickverbot.at, David Nadlinger), 21 * $(HTTP thecybershadow.net, Vladimir Panteleev) 22 * Source: $(PHOBOSSRC std/socket.d) 23 */ 24 module std.socket; 25 26 27 import core.stdc.stdint, 28 core.stdc.stdlib, 29 core.stdc.string, 30 std.string; 31 32 import hip.util.conv:to; 33 import hip.util.string:isNumber; 34 35 import core.stdc.config; 36 import std.exception; 37 38 import std.internal.cstring; 39 40 version (iOS) 41 version = iOSDerived; 42 else version (TVOS) 43 version = iOSDerived; 44 else version (WatchOS) 45 version = iOSDerived; 46 47 @safe: 48 49 version(Posix) version = LinuxLike; 50 version(PSVita) version = LinuxLike; 51 52 version(PSVita): 53 54 version (Windows) 55 { 56 pragma (lib, "ws2_32.lib"); 57 pragma (lib, "wsock32.lib"); 58 59 import core.sys.windows.winbase, std.windows.syserror; 60 public import core.sys.windows.winsock2; 61 private alias _ctimeval = core.sys.windows.winsock2.timeval; 62 private alias _clinger = core.sys.windows.winsock2.linger; 63 64 enum socket_t : SOCKET { INVALID_SOCKET } 65 private const int _SOCKET_ERROR = SOCKET_ERROR; 66 67 68 private int _lasterr() nothrow @nogc 69 { 70 return WSAGetLastError(); 71 } 72 } 73 else version (LinuxLike) 74 { 75 version (linux) 76 { 77 enum : int 78 { 79 TCP_KEEPIDLE = 4, 80 TCP_KEEPINTVL = 5 81 } 82 public import core.sys.posix.netinet.in_; 83 import core.sys.posix.arpa.inet; 84 import core.sys.posix.fcntl; 85 import core.sys.posix.netdb; 86 import core.sys.posix.netinet.tcp; 87 import core.sys.posix.sys.select; 88 import core.sys.posix.sys.socket; 89 import core.sys.posix.sys.time; 90 import core.sys.posix.sys.un : sockaddr_un; 91 import core.sys.posix.unistd; 92 private alias _ctimeval = core.sys.posix.sys.time.timeval; 93 private alias _clinger = core.sys.posix.sys.socket.linger; 94 import core.stdc.errno; 95 96 } 97 else version(PSVita) 98 { 99 import std.vita.tcp; 100 import std.vita.inet; 101 import std.vita.endian; 102 import std.vita.errno; 103 import std.vita.socket; 104 import std.vita.compat; 105 import std.vita.netinet_in; 106 import std.vita.netdb; 107 108 enum O_NONBLOCK = 0x4000; 109 enum F_GETFL = 3; 110 enum F_SETFL = 4; 111 @nogc @trusted nothrow extern(C) extern int fcntl (int, int, ...); 112 @nogc @trusted nothrow extern(C) int close(int); 113 114 extern(C) int gethostname(char*, size_t); 115 protoent* getprotobyname(T)(T str){return null; } 116 117 extern(C) @nogc @trusted nothrow int select(int, fd_set*, fd_set*, fd_set*, timeval*); 118 } 119 120 121 122 enum socket_t : int32_t { _init = -1 } 123 private const int _SOCKET_ERROR = -1; 124 125 private enum : int 126 { 127 SD_RECEIVE = SHUT_RD, 128 SD_SEND = SHUT_WR, 129 SD_BOTH = SHUT_RDWR 130 } 131 132 private int _lasterr() nothrow @nogc 133 { 134 return errno; 135 } 136 } 137 else 138 { 139 static assert(0, "No socket support for this platform yet."); 140 } 141 142 143 /// Base exception thrown by `std.socket`. 144 class SocketException: Exception 145 { 146 mixin basicExceptionCtors; 147 } 148 149 version (CRuntime_Glibc) version = GNU_STRERROR; 150 version (CRuntime_UClibc) version = GNU_STRERROR; 151 152 /* 153 * Needs to be public so that SocketOSException can be thrown outside of 154 * std.socket (since it uses it as a default argument), but it probably doesn't 155 * need to actually show up in the docs, since there's not really any public 156 * need for it outside of being a default argument. 157 */ 158 string formatSocketError(int err) @trusted 159 { 160 version (LinuxLike) 161 { 162 char[80] buf; 163 const(char)* cs; 164 version (GNU_STRERROR) 165 { 166 cs = strerror_r(err, buf.ptr, buf.length); 167 } 168 else 169 { 170 auto errs = strerror_r(err, buf.ptr, buf.length); 171 if (errs == 0) 172 cs = buf.ptr; 173 else 174 return "Socket error " ~ to!string(err); 175 } 176 177 auto len = strlen(cs); 178 179 if (cs[len - 1] == '\n') 180 len--; 181 if (cs[len - 1] == '\r') 182 len--; 183 return cs[0 .. len].idup; 184 } 185 else 186 version (Windows) 187 { 188 return generateSysErrorMsg(err); 189 } 190 else 191 return "Socket error " ~ to!string(err); 192 } 193 194 /// Returns the error message of the most recently encountered network error. 195 @property string lastSocketError() 196 { 197 return formatSocketError(_lasterr()); 198 } 199 200 /// Socket exception representing network errors reported by the operating system. 201 class SocketOSException: SocketException 202 { 203 int errorCode; /// Platform-specific error code. 204 205 /// 206 this(string msg, 207 string file = __FILE__, 208 size_t line = __LINE__, 209 Throwable next = null, 210 int err = _lasterr(), 211 string function(int) @trusted errorFormatter = &formatSocketError) 212 { 213 errorCode = err; 214 215 if (msg.length) 216 super(msg ~ ": " ~ errorFormatter(err), file, line, next); 217 else 218 super(errorFormatter(err), file, line, next); 219 } 220 221 /// 222 this(string msg, 223 Throwable next, 224 string file = __FILE__, 225 size_t line = __LINE__, 226 int err = _lasterr(), 227 string function(int) @trusted errorFormatter = &formatSocketError) 228 { 229 this(msg, file, line, next, err, errorFormatter); 230 } 231 232 /// 233 this(string msg, 234 int err, 235 string function(int) @trusted errorFormatter = &formatSocketError, 236 string file = __FILE__, 237 size_t line = __LINE__, 238 Throwable next = null) 239 { 240 this(msg, file, line, next, err, errorFormatter); 241 } 242 } 243 244 /// Socket exception representing invalid parameters specified by user code. 245 class SocketParameterException: SocketException 246 { 247 mixin basicExceptionCtors; 248 } 249 250 /** 251 * Socket exception representing attempts to use network capabilities not 252 * available on the current system. 253 */ 254 class SocketFeatureException: SocketException 255 { 256 mixin basicExceptionCtors; 257 } 258 259 260 /** 261 * Returns: 262 * `true` if the last socket operation failed because the socket 263 * was in non-blocking mode and the operation would have blocked, 264 * or if the socket is in blocking mode and set a `SNDTIMEO` or `RCVTIMEO`, 265 * and the operation timed out. 266 */ 267 bool wouldHaveBlocked() nothrow @nogc 268 { 269 version (Windows) 270 return _lasterr() == WSAEWOULDBLOCK || _lasterr() == WSAETIMEDOUT; 271 else version (LinuxLike) 272 return _lasterr() == EAGAIN; 273 else 274 static assert(0, "No socket support for this platform yet."); 275 } 276 277 278 version(Windows) 279 { 280 private immutable 281 { 282 typeof(&getnameinfo) getnameinfoPointer; 283 typeof(&getaddrinfo) getaddrinfoPointer; 284 typeof(&freeaddrinfo) freeaddrinfoPointer; 285 } 286 } 287 else 288 { 289 private immutable 290 { 291 typeof(&getaddrinfo) getaddrinfoPointer = &getaddrinfo; 292 typeof(&freeaddrinfo) freeaddrinfoPointer = &freeaddrinfo; 293 version(linux) 294 typeof(&getnameinfo) getnameinfoPointer = &getnameinfo; 295 } 296 } 297 298 shared static this() @system 299 { 300 version (Windows) 301 { 302 WSADATA wd; 303 304 // Winsock will still load if an older version is present. 305 // The version is just a request. 306 int val; 307 val = WSAStartup(0x2020, &wd); 308 if (val) // Request Winsock 2.2 for IPv6. 309 throw new SocketOSException("Unable to initialize socket library", val); 310 311 // These functions may not be present on older Windows versions. 312 // See the comment in InternetAddress.toHostNameString() for details. 313 auto ws2Lib = GetModuleHandleA("ws2_32.dll"); 314 if (ws2Lib) 315 { 316 getnameinfoPointer = cast(typeof(getnameinfoPointer)) 317 GetProcAddress(ws2Lib, "getnameinfo"); 318 getaddrinfoPointer = cast(typeof(getaddrinfoPointer)) 319 GetProcAddress(ws2Lib, "getaddrinfo"); 320 freeaddrinfoPointer = cast(typeof(freeaddrinfoPointer)) 321 GetProcAddress(ws2Lib, "freeaddrinfo"); 322 } 323 } 324 } 325 326 327 328 version(Windows) 329 { 330 shared static ~this() @system nothrow @nogc 331 { 332 WSACleanup(); 333 } 334 } 335 336 337 /** 338 * The communication domain used to resolve an address. 339 */ 340 enum AddressFamily: ushort 341 { 342 UNSPEC = AF_UNSPEC, /// Unspecified address family 343 UNIX = AF_UNIX, /// Local communication (Unix socket) 344 INET = AF_INET, /// Internet Protocol version 4 345 IPX = AF_IPX, /// Novell IPX 346 APPLETALK = AF_APPLETALK, /// AppleTalk 347 INET6 = AF_INET6, /// Internet Protocol version 6 348 } 349 350 351 /** 352 * Communication semantics 353 */ 354 enum SocketType: int 355 { 356 STREAM = SOCK_STREAM, /// Sequenced, reliable, two-way communication-based byte streams 357 DGRAM = SOCK_DGRAM, /// Connectionless, unreliable datagrams with a fixed maximum length; data may be lost or arrive out of order 358 RAW = SOCK_RAW, /// Raw protocol access 359 RDM = SOCK_RDM, /// Reliably-delivered message datagrams 360 SEQPACKET = SOCK_SEQPACKET, /// Sequenced, reliable, two-way connection-based datagrams with a fixed maximum length 361 } 362 363 version(PSVita) 364 { 365 /** 366 * Protocol 367 */ 368 enum ProtocolType: int 369 { 370 IP = IPPROTO_IP, /// Internet Protocol version 4 371 ICMP = IPPROTO_ICMP, /// Internet Control Message Protocol 372 IGMP = IPPROTO_IGMP, /// Internet Group Management Protocol 373 TCP = IPPROTO_TCP, /// Transmission Control Protocol 374 UDP = IPPROTO_UDP, /// User Datagram Protocol 375 IPV6 = IPPROTO_IPV6, /// Internet Protocol version 6 376 377 GGP = int.max, 378 PUP = int.max, 379 IDP = int.max, 380 RAW = int.max, /// Raw IP packets 381 } 382 } 383 else 384 { 385 /** 386 * Protocol 387 */ 388 enum ProtocolType: int 389 { 390 IP = IPPROTO_IP, /// Internet Protocol version 4 391 ICMP = IPPROTO_ICMP, /// Internet Control Message Protocol 392 IGMP = IPPROTO_IGMP, /// Internet Group Management Protocol 393 GGP = IPPROTO_GGP, /// Gateway to Gateway Protocol 394 TCP = IPPROTO_TCP, /// Transmission Control Protocol 395 PUP = IPPROTO_PUP, /// PARC Universal Packet Protocol 396 UDP = IPPROTO_UDP, /// User Datagram Protocol 397 IDP = IPPROTO_IDP, /// Xerox NS protocol 398 RAW = IPPROTO_RAW, /// Raw IP packets 399 IPV6 = IPPROTO_IPV6, /// Internet Protocol version 6 400 } 401 } 402 403 404 405 /** 406 * Class for retrieving protocol information. 407 * 408 * Example: 409 * --- 410 * auto proto = new Protocol; 411 * writeln("About protocol TCP:"); 412 * if (proto.getProtocolByType(ProtocolType.TCP)) 413 * { 414 * writefln(" Name: %s", proto.name); 415 * foreach (string s; proto.aliases) 416 * writefln(" Alias: %s", s); 417 * } 418 * else 419 * writeln(" No information found"); 420 * --- 421 */ 422 // class Protocol 423 // { 424 // /// These members are populated when one of the following functions are called successfully: 425 // ProtocolType type; 426 // string name; /// ditto 427 // string[] aliases; /// ditto 428 429 430 // void populate(protoent* proto) @system pure nothrow 431 // { 432 // type = cast(ProtocolType) proto.p_proto; 433 // name = to!string(proto.p_name); 434 435 // int i; 436 // for (i = 0;; i++) 437 // { 438 // if (!proto.p_aliases[i]) 439 // break; 440 // } 441 442 // if (i) 443 // { 444 // aliases = new string[i]; 445 // for (i = 0; i != aliases.length; i++) 446 // { 447 // aliases[i] = 448 // to!string(proto.p_aliases[i]); 449 // } 450 // } 451 // else 452 // { 453 // aliases = null; 454 // } 455 // } 456 457 // /** Returns: false on failure */ 458 // bool getProtocolByName(scope const(char)[] name) @trusted nothrow 459 // { 460 // protoent* proto; 461 // proto = getprotobyname(name.tempCString()); 462 // if (!proto) 463 // return false; 464 // populate(proto); 465 // return true; 466 // } 467 468 469 // /** Returns: false on failure */ 470 // // Same as getprotobynumber(). 471 // bool getProtocolByType(ProtocolType type) @trusted nothrow 472 // { 473 // protoent* proto; 474 // proto = getprotobynumber(type); 475 // if (!proto) 476 // return false; 477 // populate(proto); 478 // return true; 479 // } 480 // } 481 482 483 484 /** 485 * Class for retrieving service information. 486 * 487 * Example: 488 * --- 489 * auto serv = new Service; 490 * writeln("About service epmap:"); 491 * if (serv.getServiceByName("epmap", "tcp")) 492 * { 493 * writefln(" Service: %s", serv.name); 494 * writefln(" Port: %d", serv.port); 495 * writefln(" Protocol: %s", serv.protocolName); 496 * foreach (string s; serv.aliases) 497 * writefln(" Alias: %s", s); 498 * } 499 * else 500 * writefln(" No service for epmap."); 501 * --- 502 */ 503 class Service 504 { 505 /// These members are populated when one of the following functions are called successfully: 506 string name; 507 string[] aliases; /// ditto 508 ushort port; /// ditto 509 string protocolName; /// ditto 510 511 512 void populate(servent* serv) @system pure nothrow 513 { 514 name = to!string(serv.s_name); 515 port = ntohs(cast(ushort) serv.s_port); 516 protocolName = to!string(serv.s_proto); 517 518 int i; 519 for (i = 0;; i++) 520 { 521 if (!serv.s_aliases[i]) 522 break; 523 } 524 525 if (i) 526 { 527 aliases = new string[i]; 528 for (i = 0; i != aliases.length; i++) 529 { 530 aliases[i] = 531 to!string(serv.s_aliases[i]); 532 } 533 } 534 else 535 { 536 aliases = null; 537 } 538 } 539 540 /** 541 * If a protocol name is omitted, any protocol will be matched. 542 * Returns: false on failure. 543 */ 544 bool getServiceByName(scope const(char)[] name, scope const(char)[] protocolName = null) @trusted nothrow 545 { 546 servent* serv; 547 serv = getservbyname(name.tempCString(), protocolName.tempCString()); 548 if (!serv) 549 return false; 550 populate(serv); 551 return true; 552 } 553 554 555 /// ditto 556 bool getServiceByPort(ushort port, scope const(char)[] protocolName = null) @trusted nothrow 557 { 558 servent* serv; 559 serv = getservbyport(port, protocolName.tempCString()); 560 if (!serv) 561 return false; 562 populate(serv); 563 return true; 564 } 565 } 566 567 568 569 private mixin template socketOSExceptionCtors() 570 { 571 /// 572 this(string msg, string file = __FILE__, size_t line = __LINE__, 573 Throwable next = null, int err = _lasterr()) 574 { 575 super(msg, file, line, next, err); 576 } 577 578 /// 579 this(string msg, Throwable next, string file = __FILE__, 580 size_t line = __LINE__, int err = _lasterr()) 581 { 582 super(msg, next, file, line, err); 583 } 584 585 /// 586 this(string msg, int err, string file = __FILE__, size_t line = __LINE__, 587 Throwable next = null) 588 { 589 super(msg, next, file, line, err); 590 } 591 } 592 593 594 /** 595 * Class for exceptions thrown from an `InternetHost`. 596 */ 597 class HostException: SocketOSException 598 { 599 mixin socketOSExceptionCtors; 600 } 601 602 /** 603 * Class for resolving IPv4 addresses. 604 * 605 * Consider using `getAddress`, `parseAddress` and `Address` methods 606 * instead of using this class directly. 607 */ 608 class InternetHost 609 { 610 /// These members are populated when one of the following functions are called successfully: 611 string name; 612 string[] aliases; /// ditto 613 uint[] addrList; /// ditto 614 615 616 void validHostent(in hostent* he) 617 { 618 if (he.h_addrtype != cast(int) AddressFamily.INET || he.h_length != 4) 619 throw new HostException("Address family mismatch"); 620 } 621 622 623 void populate(hostent* he) @system pure nothrow 624 { 625 int i; 626 char* p; 627 628 name = to!string(he.h_name); 629 630 for (i = 0;; i++) 631 { 632 p = he.h_aliases[i]; 633 if (!p) 634 break; 635 } 636 637 if (i) 638 { 639 aliases = new string[i]; 640 for (i = 0; i != aliases.length; i++) 641 { 642 aliases[i] = 643 to!string(he.h_aliases[i]); 644 } 645 } 646 else 647 { 648 aliases = null; 649 } 650 651 for (i = 0;; i++) 652 { 653 p = he.h_addr_list[i]; 654 if (!p) 655 break; 656 } 657 658 if (i) 659 { 660 addrList = new uint[i]; 661 for (i = 0; i != addrList.length; i++) 662 { 663 addrList[i] = ntohl(*(cast(uint*) he.h_addr_list[i])); 664 } 665 } 666 else 667 { 668 addrList = null; 669 } 670 } 671 672 private bool getHostNoSync(string opMixin, T)(T param) @system 673 { 674 mixin(opMixin); 675 if (!he) 676 return false; 677 validHostent(he); 678 populate(he); 679 return true; 680 } 681 682 version (Windows) 683 alias getHost = getHostNoSync; 684 else 685 { 686 // posix systems use global state for return value, so we 687 // must synchronize across all threads 688 private bool getHost(string opMixin, T)(T param) @system 689 { 690 // synchronized(this.classinfo) 691 return getHostNoSync!(opMixin, T)(param); 692 } 693 } 694 695 /** 696 * Resolve host name. 697 * Returns: false if unable to resolve. 698 */ 699 bool getHostByName(scope const(char)[] name) @trusted 700 { 701 static if (is(typeof(gethostbyname_r))) 702 { 703 return getHostNoSync!q{ 704 hostent he_v; 705 hostent* he; 706 ubyte[256] buffer_v = void; 707 auto buffer = buffer_v[]; 708 auto param_zTmp = param.tempCString(); 709 while (true) 710 { 711 he = &he_v; 712 int errno; 713 if (gethostbyname_r(param_zTmp, he, buffer.ptr, buffer.length, &he, &errno) == ERANGE) 714 buffer.length = buffer.length * 2; 715 else 716 break; 717 } 718 }(name); 719 } 720 else 721 { 722 return getHost!q{ 723 auto he = gethostbyname(param.tempCString()); 724 }(name); 725 } 726 } 727 728 /** 729 * Resolve IPv4 address number. 730 * 731 * Params: 732 * addr = The IPv4 address to resolve, in host byte order. 733 * Returns: 734 * false if unable to resolve. 735 */ 736 bool getHostByAddr(uint addr) @trusted 737 { 738 return getHost!q{ 739 auto x = htonl(param); 740 auto he = gethostbyaddr(&x, 4, cast(int) AddressFamily.INET); 741 }(addr); 742 } 743 744 /** 745 * Same as previous, but addr is an IPv4 address string in the 746 * dotted-decimal form $(I a.b.c.d). 747 * Returns: false if unable to resolve. 748 */ 749 bool getHostByAddr(scope const(char)[] addr) @trusted 750 { 751 return getHost!q{ 752 auto x = inet_addr(param.tempCString()); 753 enforce(x != INADDR_NONE, 754 new SocketParameterException("Invalid IPv4 address")); 755 auto he = gethostbyaddr(&x, 4, cast(int) AddressFamily.INET); 756 }(addr); 757 } 758 } 759 760 /// 761 762 763 764 /// Holds information about a socket _address retrieved by `getAddressInfo`. 765 struct AddressInfo 766 { 767 AddressFamily family; /// Address _family 768 SocketType type; /// Socket _type 769 ProtocolType protocol; /// Protocol 770 Address address; /// Socket _address 771 string canonicalName; /// Canonical name, when `AddressInfoFlags.CANONNAME` is used. 772 } 773 774 /** 775 * A subset of flags supported on all platforms with getaddrinfo. 776 * Specifies option flags for `getAddressInfo`. 777 */ 778 enum AddressInfoFlags: int 779 { 780 /// The resulting addresses will be used in a call to `Socket.bind`. 781 PASSIVE = AI_PASSIVE, 782 783 /// The canonical name is returned in `canonicalName` member in the first `AddressInfo`. 784 CANONNAME = AI_CANONNAME, 785 786 /** 787 * The `node` parameter passed to `getAddressInfo` must be a numeric string. 788 * This will suppress any potentially lengthy network host address lookups. 789 */ 790 NUMERICHOST = AI_NUMERICHOST, 791 } 792 793 794 /** 795 * On POSIX, getaddrinfo uses its own error codes, and thus has its own 796 * formatting function. 797 */ 798 private string formatGaiError(int err) @trusted 799 { 800 version (Windows) 801 { 802 return generateSysErrorMsg(err); 803 } 804 else 805 { 806 // synchronized 807 return to!string(gai_strerror(err)); 808 } 809 } 810 811 /** 812 * Provides _protocol-independent translation from host names to socket 813 * addresses. If advanced functionality is not required, consider using 814 * `getAddress` for compatibility with older systems. 815 * 816 * Returns: Array with one `AddressInfo` per socket address. 817 * 818 * Throws: `SocketOSException` on failure, or `SocketFeatureException` 819 * if this functionality is not available on the current system. 820 * 821 * Params: 822 * node = string containing host name or numeric address 823 * options = optional additional parameters, identified by type: 824 * $(UL $(LI `string` - service name or port number) 825 * $(LI `AddressInfoFlags` - option flags) 826 * $(LI `AddressFamily` - address family to filter by) 827 * $(LI `SocketType` - socket type to filter by) 828 * $(LI `ProtocolType` - protocol to filter by)) 829 * 830 * Example: 831 * --- 832 * // Roundtrip DNS resolution 833 * auto results = getAddressInfo("www.digitalmars.com"); 834 * assert(results[0].address.toHostNameString() == 835 * "digitalmars.com"); 836 * 837 * // Canonical name 838 * results = getAddressInfo("www.digitalmars.com", 839 * AddressInfoFlags.CANONNAME); 840 * assert(results[0].canonicalName == "digitalmars.com"); 841 * 842 * // IPv6 resolution 843 * results = getAddressInfo("ipv6.google.com"); 844 * assert(results[0].family == AddressFamily.INET6); 845 * 846 * // Multihomed resolution 847 * results = getAddressInfo("google.com"); 848 * assert(results.length > 1); 849 * 850 * // Parsing IPv4 851 * results = getAddressInfo("127.0.0.1", 852 * AddressInfoFlags.NUMERICHOST); 853 * assert(results.length && results[0].family == 854 * AddressFamily.INET); 855 * 856 * // Parsing IPv6 857 * results = getAddressInfo("::1", 858 * AddressInfoFlags.NUMERICHOST); 859 * assert(results.length && results[0].family == 860 * AddressFamily.INET6); 861 * --- 862 */ 863 AddressInfo[] getAddressInfo(T...)(scope const(char)[] node, scope T options) 864 { 865 const(char)[] service = null; 866 addrinfo hints; 867 hints.ai_family = AF_UNSPEC; 868 869 foreach (i, option; options) 870 { 871 static if (is(typeof(option) : const(char)[])) 872 service = options[i]; 873 else 874 static if (is(typeof(option) == AddressInfoFlags)) 875 hints.ai_flags |= option; 876 else 877 static if (is(typeof(option) == AddressFamily)) 878 hints.ai_family = option; 879 else 880 static if (is(typeof(option) == SocketType)) 881 hints.ai_socktype = option; 882 else 883 static if (is(typeof(option) == ProtocolType)) 884 hints.ai_protocol = option; 885 else 886 static assert(0, "Unknown getAddressInfo option type: " ~ typeof(option).stringof); 887 } 888 889 return () @trusted { return getAddressInfoImpl(node, service, &hints); }(); 890 } 891 892 893 private AddressInfo[] getAddressInfoImpl(scope const(char)[] node, scope const(char)[] service, addrinfo* hints) @system 894 { 895 896 if (getaddrinfoPointer && freeaddrinfoPointer) 897 { 898 addrinfo* ai_res; 899 900 int ret = getaddrinfoPointer( 901 node.tempCString(), 902 service.tempCString(), 903 hints, &ai_res); 904 enforce(ret == 0, new SocketOSException("getaddrinfo error", ret, &formatGaiError)); 905 scope(exit) freeaddrinfoPointer(ai_res); 906 907 AddressInfo[] result; 908 909 // Use const to force UnknownAddressReference to copy the sockaddr. 910 for (const(addrinfo)* ai = ai_res; ai; ai = ai.ai_next) 911 result ~= AddressInfo( 912 cast(AddressFamily) ai.ai_family, 913 cast(SocketType ) ai.ai_socktype, 914 cast(ProtocolType ) ai.ai_protocol, 915 new UnknownAddressReference(ai.ai_addr, cast(socklen_t) ai.ai_addrlen), 916 ai.ai_canonname ? to!string(ai.ai_canonname) : null); 917 918 return result; 919 } 920 921 throw new SocketFeatureException("Address info lookup is not available " ~ 922 "on this system."); 923 } 924 925 926 927 private ushort serviceToPort(scope const(char)[] service) 928 { 929 if (service == "") 930 return InternetAddress.PORT_ANY; 931 else 932 if (isNumber(service)) 933 return to!ushort(service); 934 else 935 { 936 auto s = new Service(); 937 s.getServiceByName(service); 938 return s.port; 939 } 940 } 941 942 /** 943 * Provides _protocol-independent translation from host names to socket 944 * addresses. Uses `getAddressInfo` if the current system supports it, 945 * and `InternetHost` otherwise. 946 * 947 * Returns: Array with one `Address` instance per socket address. 948 * 949 * Throws: `SocketOSException` on failure. 950 * 951 * Example: 952 * --- 953 * writeln("Resolving www.digitalmars.com:"); 954 * try 955 * { 956 * auto addresses = getAddress("www.digitalmars.com"); 957 * foreach (address; addresses) 958 * writefln(" IP: %s", address.toAddrString()); 959 * } 960 * catch (SocketException e) 961 * writefln(" Lookup failed: %s", e.msg); 962 * --- 963 */ 964 Address[] getAddress(scope const(char)[] hostname, scope const(char)[] service = null) 965 { 966 if (getaddrinfoPointer && freeaddrinfoPointer) 967 { 968 // use getAddressInfo 969 auto infos = getAddressInfo(hostname, service); 970 Address[] results; 971 results.length = infos.length; 972 foreach (i, ref result; results) 973 result = infos[i].address; 974 return results; 975 } 976 else 977 return getAddress(hostname, serviceToPort(service)); 978 } 979 980 /// ditto 981 Address[] getAddress(scope const(char)[] hostname, ushort port) 982 { 983 if (getaddrinfoPointer && freeaddrinfoPointer) 984 return getAddress(hostname, to!string(port)); 985 else 986 { 987 // use getHostByName 988 auto ih = new InternetHost; 989 if (!ih.getHostByName(hostname)) 990 { 991 throw new AddressException( 992 cast(string)("Unable to resolve host '" ~hostname.idup ~"'")); 993 } 994 995 Address[] results; 996 foreach (uint addr; ih.addrList) 997 results ~= new InternetAddress(addr, port); 998 return results; 999 } 1000 } 1001 1002 1003 1004 1005 1006 /** 1007 * Provides _protocol-independent parsing of network addresses. Does not 1008 * attempt name resolution. Uses `getAddressInfo` with 1009 * `AddressInfoFlags.NUMERICHOST` if the current system supports it, and 1010 * `InternetAddress` otherwise. 1011 * 1012 * Returns: An `Address` instance representing specified address. 1013 * 1014 * Throws: `SocketException` on failure. 1015 * 1016 * Example: 1017 * --- 1018 * writeln("Enter IP address:"); 1019 * string ip = readln().chomp(); 1020 * try 1021 * { 1022 * Address address = parseAddress(ip); 1023 * writefln("Looking up reverse of %s:", 1024 * address.toAddrString()); 1025 * try 1026 * { 1027 * string reverse = address.toHostNameString(); 1028 * if (reverse) 1029 * writefln(" Reverse name: %s", reverse); 1030 * else 1031 * writeln(" Reverse hostname not found."); 1032 * } 1033 * catch (SocketException e) 1034 * writefln(" Lookup error: %s", e.msg); 1035 * } 1036 * catch (SocketException e) 1037 * { 1038 * writefln(" %s is not a valid IP address: %s", 1039 * ip, e.msg); 1040 * } 1041 * --- 1042 */ 1043 Address parseAddress(scope const(char)[] hostaddr, scope const(char)[] service = null) 1044 { 1045 if (getaddrinfoPointer && freeaddrinfoPointer) 1046 return getAddressInfo(hostaddr, service, AddressInfoFlags.NUMERICHOST)[0].address; 1047 else 1048 return parseAddress(hostaddr, serviceToPort(service)); 1049 } 1050 1051 /// ditto 1052 Address parseAddress(scope const(char)[] hostaddr, ushort port) 1053 { 1054 if (getaddrinfoPointer && freeaddrinfoPointer) 1055 return parseAddress(hostaddr, to!string(port)); 1056 else 1057 { 1058 auto in4_addr = InternetAddress.parse(hostaddr); 1059 enforce(in4_addr != InternetAddress.ADDR_NONE, 1060 new SocketParameterException("Invalid IP address")); 1061 return new InternetAddress(in4_addr, port); 1062 } 1063 } 1064 1065 1066 1067 /** 1068 * Class for exceptions thrown from an `Address`. 1069 */ 1070 class AddressException: SocketOSException 1071 { 1072 mixin socketOSExceptionCtors; 1073 } 1074 1075 1076 /** 1077 * Abstract class for representing a socket address. 1078 * 1079 * Example: 1080 * --- 1081 * writeln("About www.google.com port 80:"); 1082 * try 1083 * { 1084 * Address[] addresses = getAddress("www.google.com", 80); 1085 * writefln(" %d addresses found.", addresses.length); 1086 * foreach (int i, Address a; addresses) 1087 * { 1088 * writefln(" Address %d:", i+1); 1089 * writefln(" IP address: %s", a.toAddrString()); 1090 * writefln(" Hostname: %s", a.toHostNameString()); 1091 * writefln(" Port: %s", a.toPortString()); 1092 * writefln(" Service name: %s", 1093 * a.toServiceNameString()); 1094 * } 1095 * } 1096 * catch (SocketException e) 1097 * writefln(" Lookup error: %s", e.msg); 1098 * --- 1099 */ 1100 abstract class Address 1101 { 1102 /// Returns pointer to underlying `sockaddr` structure. 1103 abstract @property sockaddr* name() pure nothrow @nogc; 1104 abstract @property const(sockaddr)* name() const pure nothrow @nogc; /// ditto 1105 1106 /// Returns actual size of underlying `sockaddr` structure. 1107 abstract @property socklen_t nameLen() const pure nothrow @nogc; 1108 1109 // Socket.remoteAddress, Socket.localAddress, and Socket.receiveFrom 1110 // use setNameLen to set the actual size of the address as returned by 1111 // getsockname, getpeername, and recvfrom, respectively. 1112 // The following implementation is sufficient for fixed-length addresses, 1113 // and ensures that the length is not changed. 1114 // Must be overridden for variable-length addresses. 1115 protected void setNameLen(socklen_t len) 1116 { 1117 if (len != this.nameLen) 1118 throw new AddressException(typeid(this).toString ~ " expects address of length "~nameLen.to!string~", not "~len.to!string, 0); 1119 } 1120 1121 /// Family of this address. 1122 @property AddressFamily addressFamily() const pure nothrow @nogc 1123 { 1124 return cast(AddressFamily) name.sa_family; 1125 } 1126 1127 // Common code for toAddrString and toHostNameString 1128 private string toHostString(bool numeric) @trusted const 1129 { 1130 // getnameinfo() is the recommended way to perform a reverse (name) 1131 // lookup on both Posix and Windows. However, it is only available 1132 // on Windows XP and above, and not included with the WinSock import 1133 // libraries shipped with DMD. Thus, we check for getnameinfo at 1134 // runtime in the shared module constructor, and use it if it's 1135 // available in the base class method. Classes for specific network 1136 // families (e.g. InternetHost) override this method and use a 1137 // deprecated, albeit commonly-available method when getnameinfo() 1138 // is not available. 1139 // http://technet.microsoft.com/en-us/library/aa450403.aspx 1140 1141 throw new SocketFeatureException((numeric ? "Host address" : "Host name") ~ 1142 " lookup for this address family is not available on this system."); 1143 } 1144 1145 // Common code for toPortString and toServiceNameString 1146 private string toServiceString(bool numeric) @trusted const 1147 { 1148 // See toHostNameString() for details about getnameinfo(). 1149 1150 throw new SocketFeatureException((numeric ? "Port number" : "Service name") ~ 1151 " lookup for this address family is not available on this system."); 1152 } 1153 1154 /** 1155 * Attempts to retrieve the host address as a human-readable string. 1156 * 1157 * Throws: `AddressException` on failure, or `SocketFeatureException` 1158 * if address retrieval for this address family is not available on the 1159 * current system. 1160 */ 1161 string toAddrString() const 1162 { 1163 return toHostString(true); 1164 } 1165 1166 /** 1167 * Attempts to retrieve the host name as a fully qualified domain name. 1168 * 1169 * Returns: The FQDN corresponding to this `Address`, or `null` if 1170 * the host name did not resolve. 1171 * 1172 * Throws: `AddressException` on error, or `SocketFeatureException` 1173 * if host name lookup for this address family is not available on the 1174 * current system. 1175 */ 1176 string toHostNameString() const 1177 { 1178 return toHostString(false); 1179 } 1180 1181 /** 1182 * Attempts to retrieve the numeric port number as a string. 1183 * 1184 * Throws: `AddressException` on failure, or `SocketFeatureException` 1185 * if port number retrieval for this address family is not available on the 1186 * current system. 1187 */ 1188 string toPortString() const 1189 { 1190 return toServiceString(true); 1191 } 1192 1193 /** 1194 * Attempts to retrieve the service name as a string. 1195 * 1196 * Throws: `AddressException` on failure, or `SocketFeatureException` 1197 * if service name lookup for this address family is not available on the 1198 * current system. 1199 */ 1200 string toServiceNameString() const 1201 { 1202 return toServiceString(false); 1203 } 1204 1205 /// Human readable string representing this address. 1206 override string toString() const 1207 { 1208 try 1209 { 1210 string host = toAddrString(); 1211 string port = toPortString(); 1212 if (host.indexOf(":") >= 0) 1213 return "[" ~ host ~ "]:" ~ port; 1214 else 1215 return host ~ ":" ~ port; 1216 } 1217 catch (SocketException) 1218 return "Unknown"; 1219 } 1220 } 1221 1222 /** 1223 * Encapsulates an unknown socket address. 1224 */ 1225 class UnknownAddress: Address 1226 { 1227 protected: 1228 sockaddr sa; 1229 1230 1231 public: 1232 override @property sockaddr* name() return 1233 { 1234 return &sa; 1235 } 1236 1237 override @property const(sockaddr)* name() const return 1238 { 1239 return &sa; 1240 } 1241 1242 1243 override @property socklen_t nameLen() const 1244 { 1245 return cast(socklen_t) sa.sizeof; 1246 } 1247 1248 } 1249 1250 1251 /** 1252 * Encapsulates a reference to an arbitrary 1253 * socket address. 1254 */ 1255 class UnknownAddressReference: Address 1256 { 1257 protected: 1258 sockaddr* sa; 1259 socklen_t len; 1260 1261 public: 1262 /// Constructs an `Address` with a reference to the specified `sockaddr`. 1263 this(sockaddr* sa, socklen_t len) pure nothrow @nogc 1264 { 1265 this.sa = sa; 1266 this.len = len; 1267 } 1268 1269 /// Constructs an `Address` with a copy of the specified `sockaddr`. 1270 this(const(sockaddr)* sa, socklen_t len) @system pure nothrow 1271 { 1272 this.sa = cast(sockaddr*) (cast(ubyte*) sa)[0 .. len].dup.ptr; 1273 this.len = len; 1274 } 1275 1276 override @property sockaddr* name() 1277 { 1278 return sa; 1279 } 1280 1281 override @property const(sockaddr)* name() const 1282 { 1283 return sa; 1284 } 1285 1286 1287 override @property socklen_t nameLen() const 1288 { 1289 return cast(socklen_t) len; 1290 } 1291 } 1292 1293 1294 /** 1295 * Encapsulates an IPv4 (Internet Protocol version 4) socket address. 1296 * 1297 * Consider using `getAddress`, `parseAddress` and `Address` methods 1298 * instead of using this class directly. 1299 */ 1300 class InternetAddress: Address 1301 { 1302 protected: 1303 sockaddr_in sin; 1304 1305 1306 this() pure nothrow @nogc 1307 { 1308 } 1309 1310 1311 public: 1312 override @property sockaddr* name() return 1313 { 1314 return cast(sockaddr*)&sin; 1315 } 1316 1317 override @property const(sockaddr)* name() const return 1318 { 1319 return cast(const(sockaddr)*)&sin; 1320 } 1321 1322 1323 override @property socklen_t nameLen() const 1324 { 1325 return cast(socklen_t) sin.sizeof; 1326 } 1327 1328 1329 enum uint ADDR_ANY = INADDR_ANY; /// Any IPv4 host address. 1330 enum uint ADDR_NONE = INADDR_NONE; /// An invalid IPv4 host address. 1331 enum ushort PORT_ANY = 0; /// Any IPv4 port number. 1332 1333 /// Returns the IPv4 _port number (in host byte order). 1334 @property ushort port() const pure nothrow @nogc 1335 { 1336 return ntohs(sin.sin_port); 1337 } 1338 1339 /// Returns the IPv4 address number (in host byte order). 1340 @property uint addr() const pure nothrow @nogc 1341 { 1342 return ntohl(sin.sin_addr.s_addr); 1343 } 1344 1345 /** 1346 * Construct a new `InternetAddress`. 1347 * Params: 1348 * addr = an IPv4 address string in the dotted-decimal form a.b.c.d, 1349 * or a host name which will be resolved using an `InternetHost` 1350 * object. 1351 * port = port number, may be `PORT_ANY`. 1352 */ 1353 this(scope const(char)[] addr, ushort port) 1354 { 1355 uint uiaddr = parse(addr); 1356 if (ADDR_NONE == uiaddr) 1357 { 1358 InternetHost ih = new InternetHost; 1359 if (!ih.getHostByName(addr)) 1360 //throw new AddressException("Invalid internet address"); 1361 throw new AddressException( 1362 "Unable to resolve host '"~ addr.idup~ "'"); 1363 uiaddr = ih.addrList[0]; 1364 } 1365 sin.sin_family = AddressFamily.INET; 1366 sin.sin_addr.s_addr = htonl(uiaddr); 1367 sin.sin_port = htons(port); 1368 } 1369 1370 /** 1371 * Construct a new `InternetAddress`. 1372 * Params: 1373 * addr = (optional) an IPv4 address in host byte order, may be `ADDR_ANY`. 1374 * port = port number, may be `PORT_ANY`. 1375 */ 1376 this(uint addr, ushort port) pure nothrow @nogc 1377 { 1378 sin.sin_family = AddressFamily.INET; 1379 sin.sin_addr.s_addr = htonl(addr); 1380 sin.sin_port = htons(port); 1381 } 1382 1383 /// ditto 1384 this(ushort port) pure nothrow @nogc 1385 { 1386 sin.sin_family = AddressFamily.INET; 1387 sin.sin_addr.s_addr = ADDR_ANY; 1388 sin.sin_port = htons(port); 1389 } 1390 1391 /** 1392 * Construct a new `InternetAddress`. 1393 * Params: 1394 * addr = A sockaddr_in as obtained from lower-level API calls such as getifaddrs. 1395 */ 1396 this(sockaddr_in addr) pure nothrow @nogc 1397 { 1398 assert(addr.sin_family == AddressFamily.INET, "Socket address is not of INET family."); 1399 sin = addr; 1400 } 1401 1402 /// Human readable string representing the IPv4 address in dotted-decimal form. 1403 override string toAddrString() @trusted const 1404 { 1405 return to!string(inet_ntoa(sin.sin_addr)); 1406 } 1407 1408 /// Human readable string representing the IPv4 port. 1409 override string toPortString() const 1410 { 1411 return to!string(port); 1412 } 1413 1414 /** 1415 * Attempts to retrieve the host name as a fully qualified domain name. 1416 * 1417 * Returns: The FQDN corresponding to this `InternetAddress`, or 1418 * `null` if the host name did not resolve. 1419 * 1420 * Throws: `AddressException` on error. 1421 */ 1422 override string toHostNameString() const 1423 { 1424 // getnameinfo() is the recommended way to perform a reverse (name) 1425 // lookup on both Posix and Windows. However, it is only available 1426 // on Windows XP and above, and not included with the WinSock import 1427 // libraries shipped with DMD. Thus, we check for getnameinfo at 1428 // runtime in the shared module constructor, and fall back to the 1429 // deprecated getHostByAddr() if it could not be found. See also: 1430 // http://technet.microsoft.com/en-us/library/aa450403.aspx 1431 1432 auto host = new InternetHost(); 1433 if (!host.getHostByAddr(ntohl(sin.sin_addr.s_addr))) 1434 return null; 1435 return host.name; 1436 } 1437 1438 /** 1439 * Provides support for comparing equality with another 1440 * InternetAddress of the same type. 1441 * Returns: true if the InternetAddresses share the same address and 1442 * port number. 1443 */ 1444 override bool opEquals(Object o) const 1445 { 1446 auto other = cast(InternetAddress) o; 1447 return other && this.sin.sin_addr.s_addr == other.sin.sin_addr.s_addr && 1448 this.sin.sin_port == other.sin.sin_port; 1449 } 1450 1451 /// 1452 1453 1454 /** 1455 * Parse an IPv4 address string in the dotted-decimal form $(I a.b.c.d) 1456 * and return the number. 1457 * Returns: If the string is not a legitimate IPv4 address, 1458 * `ADDR_NONE` is returned. 1459 */ 1460 static uint parse(scope const(char)[] addr) @trusted nothrow 1461 { 1462 return ntohl(inet_addr(addr.tempCString())); 1463 } 1464 1465 /** 1466 * Convert an IPv4 address number in host byte order to a human readable 1467 * string representing the IPv4 address in dotted-decimal form. 1468 */ 1469 static string addrToString(uint addr) @trusted nothrow 1470 { 1471 in_addr sin_addr; 1472 sin_addr.s_addr = htonl(addr); 1473 return to!string(inet_ntoa(sin_addr)); 1474 } 1475 } 1476 1477 1478 1479 /** 1480 * Encapsulates an IPv6 (Internet Protocol version 6) socket address. 1481 * 1482 * Consider using `getAddress`, `parseAddress` and `Address` methods 1483 * instead of using this class directly. 1484 */ 1485 class Internet6Address: Address 1486 { 1487 protected: 1488 sockaddr_in6 sin6; 1489 1490 1491 this() pure nothrow @nogc 1492 { 1493 } 1494 1495 1496 public: 1497 override @property sockaddr* name() return 1498 { 1499 return cast(sockaddr*)&sin6; 1500 } 1501 1502 override @property const(sockaddr)* name() const return 1503 { 1504 return cast(const(sockaddr)*)&sin6; 1505 } 1506 1507 1508 override @property socklen_t nameLen() const 1509 { 1510 return cast(socklen_t) sin6.sizeof; 1511 } 1512 1513 __gshared immutable in6_addr in6addr_any = {[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}; 1514 1515 /// Any IPv6 host address. 1516 static @property ref const(ubyte)[16] ADDR_ANY() pure nothrow @nogc 1517 { 1518 static if (is(typeof(IN6ADDR_ANY))) 1519 { 1520 version (Windows) 1521 { 1522 static immutable addr = IN6ADDR_ANY.s6_addr; 1523 return addr; 1524 } 1525 else 1526 return IN6ADDR_ANY.s6_addr; 1527 } 1528 else static if (is(typeof(in6addr_any))) 1529 { 1530 return in6addr_any.s6_addr; 1531 } 1532 else 1533 { 1534 return in6addr_any; 1535 } 1536 } 1537 1538 /// Any IPv6 port number. 1539 enum ushort PORT_ANY = 0; 1540 1541 /// Returns the IPv6 port number. 1542 @property ushort port() const pure nothrow @nogc 1543 { 1544 return ntohs(sin6.sin6_port); 1545 } 1546 1547 /// Returns the IPv6 address. 1548 @property ubyte[16] addr() const pure nothrow @nogc 1549 { 1550 return sin6.sin6_addr.s6_addr; 1551 } 1552 1553 /** 1554 * Construct a new `Internet6Address`. 1555 * Params: 1556 * addr = an IPv6 host address string in the form described in RFC 2373, 1557 * or a host name which will be resolved using `getAddressInfo`. 1558 * service = (optional) service name. 1559 */ 1560 this(scope const(char)[] addr, scope const(char)[] service = null) @trusted 1561 { 1562 auto results = getAddressInfo(addr, service, AddressFamily.INET6); 1563 assert(results.length && results[0].family == AddressFamily.INET6); 1564 sin6 = *cast(sockaddr_in6*) results[0].address.name; 1565 } 1566 1567 /** 1568 * Construct a new `Internet6Address`. 1569 * Params: 1570 * addr = an IPv6 host address string in the form described in RFC 2373, 1571 * or a host name which will be resolved using `getAddressInfo`. 1572 * port = port number, may be `PORT_ANY`. 1573 */ 1574 this(scope const(char)[] addr, ushort port) 1575 { 1576 if (port == PORT_ANY) 1577 this(addr); 1578 else 1579 this(addr, to!string(port)); 1580 } 1581 1582 /** 1583 * Construct a new `Internet6Address`. 1584 * Params: 1585 * addr = (optional) an IPv6 host address in host byte order, or 1586 * `ADDR_ANY`. 1587 * port = port number, may be `PORT_ANY`. 1588 */ 1589 this(ubyte[16] addr, ushort port) pure nothrow @nogc 1590 { 1591 sin6.sin6_family = AddressFamily.INET6; 1592 sin6.sin6_addr.s6_addr = addr; 1593 sin6.sin6_port = htons(port); 1594 } 1595 1596 /// ditto 1597 this(ushort port) pure nothrow @nogc 1598 { 1599 sin6.sin6_family = AddressFamily.INET6; 1600 sin6.sin6_addr.s6_addr = ADDR_ANY; 1601 sin6.sin6_port = htons(port); 1602 } 1603 1604 /** 1605 * Construct a new `Internet6Address`. 1606 * Params: 1607 * addr = A sockaddr_in6 as obtained from lower-level API calls such as getifaddrs. 1608 */ 1609 this(sockaddr_in6 addr) pure nothrow @nogc 1610 { 1611 assert(addr.sin6_family == AddressFamily.INET6); 1612 sin6 = addr; 1613 } 1614 1615 /** 1616 * Parse an IPv6 host address string as described in RFC 2373, and return the 1617 * address. 1618 * Throws: `SocketException` on error. 1619 */ 1620 static ubyte[16] parse(scope const(char)[] addr) @trusted 1621 { 1622 // Although we could use inet_pton here, it's only available on Windows 1623 // versions starting with Vista, so use getAddressInfo with NUMERICHOST 1624 // instead. 1625 auto results = getAddressInfo(addr, AddressInfoFlags.NUMERICHOST); 1626 if (results.length && results[0].family == AddressFamily.INET6) 1627 return (cast(sockaddr_in6*) results[0].address.name).sin6_addr.s6_addr; 1628 throw new AddressException("Not an IPv6 address", 0); 1629 } 1630 } 1631 1632 1633 1634 version (StdDdoc) 1635 { 1636 static if (!is(sockaddr_un)) 1637 { 1638 // This exists only to allow the constructor taking 1639 // a sockaddr_un to be compilable for documentation 1640 // on platforms that don't supply a sockaddr_un. 1641 struct sockaddr_un 1642 { 1643 } 1644 } 1645 1646 /** 1647 * Encapsulates an address for a Unix domain socket (`AF_UNIX`), 1648 * i.e. a socket bound to a path name in the file system. 1649 * Available only on supported systems. 1650 * 1651 * Linux also supports an abstract address namespace, in which addresses 1652 * are independent of the file system. A socket address is abstract 1653 * iff `path` starts with a _null byte (`'\0'`). Null bytes in other 1654 * positions of an abstract address are allowed and have no special 1655 * meaning. 1656 * 1657 * Example: 1658 * --- 1659 * auto addr = new UnixAddress("/var/run/dbus/system_bus_socket"); 1660 * auto abstractAddr = new UnixAddress("\0/tmp/dbus-OtHLWmCLPR"); 1661 * --- 1662 * 1663 * See_Also: $(HTTP man7.org/linux/man-pages/man7/unix.7.html, UNIX(7)) 1664 */ 1665 class UnixAddress: Address 1666 { 1667 private this() pure nothrow @nogc {} 1668 1669 /// Construct a new `UnixAddress` from the specified path. 1670 this(scope const(char)[] path) { } 1671 1672 /** 1673 * Construct a new `UnixAddress`. 1674 * Params: 1675 * addr = A sockaddr_un as obtained from lower-level API calls. 1676 */ 1677 this(sockaddr_un addr) pure nothrow @nogc { } 1678 1679 /// Get the underlying _path. 1680 @property string path() const { return null; } 1681 1682 /// ditto 1683 override string toString() const { return null; } 1684 1685 override @property sockaddr* name() { return null; } 1686 override @property const(sockaddr)* name() const { return null; } 1687 override @property socklen_t nameLen() const { return 0; } 1688 } 1689 } 1690 else 1691 static if (is(sockaddr_un)) 1692 { 1693 class UnixAddress: Address 1694 { 1695 protected: 1696 socklen_t _nameLen; 1697 1698 struct 1699 { 1700 align (1): 1701 sockaddr_un sun; 1702 char unused = '\0'; // placeholder for a terminating '\0' 1703 } 1704 1705 this() pure nothrow @nogc 1706 { 1707 sun.sun_family = AddressFamily.UNIX; 1708 sun.sun_path = '?'; 1709 _nameLen = sun.sizeof; 1710 } 1711 1712 override void setNameLen(socklen_t len) @trusted 1713 { 1714 if (len > sun.sizeof) 1715 throw new SocketParameterException("Not enough socket address storage"); 1716 _nameLen = len; 1717 } 1718 1719 public: 1720 override @property sockaddr* name() return 1721 { 1722 return cast(sockaddr*)&sun; 1723 } 1724 1725 override @property const(sockaddr)* name() const return 1726 { 1727 return cast(const(sockaddr)*)&sun; 1728 } 1729 1730 override @property socklen_t nameLen() @trusted const 1731 { 1732 return _nameLen; 1733 } 1734 1735 this(scope const(char)[] path) @trusted pure 1736 { 1737 enforce(path.length <= sun.sun_path.sizeof, new SocketParameterException("Path too long")); 1738 sun.sun_family = AddressFamily.UNIX; 1739 sun.sun_path.ptr[0 .. path.length] = (cast(byte[]) path)[]; 1740 _nameLen = cast(socklen_t) 1741 { 1742 auto len = sockaddr_un.init.sun_path.offsetof + path.length; 1743 // Pathname socket address must be terminated with '\0' 1744 // which must be included in the address length. 1745 if (sun.sun_path.ptr[0]) 1746 { 1747 sun.sun_path.ptr[path.length] = 0; 1748 ++len; 1749 } 1750 return len; 1751 }(); 1752 } 1753 1754 this(sockaddr_un addr) pure nothrow @nogc 1755 { 1756 assert(addr.sun_family == AddressFamily.UNIX); 1757 sun = addr; 1758 } 1759 1760 @property string path() @trusted const pure 1761 { 1762 auto len = _nameLen - sockaddr_un.init.sun_path.offsetof; 1763 if (len == 0) 1764 return null; // An empty path may be returned from getpeername 1765 // For pathname socket address we need to strip off the terminating '\0' 1766 if (sun.sun_path.ptr[0]) 1767 --len; 1768 return (cast(const(char)*) sun.sun_path.ptr)[0 .. len].idup; 1769 } 1770 1771 override string toString() const pure 1772 { 1773 return path; 1774 } 1775 } 1776 1777 } 1778 1779 1780 /** 1781 * Exception thrown by `Socket.accept`. 1782 */ 1783 class SocketAcceptException: SocketOSException 1784 { 1785 mixin socketOSExceptionCtors; 1786 } 1787 1788 /// How a socket is shutdown: 1789 enum SocketShutdown: int 1790 { 1791 RECEIVE = SD_RECEIVE, /// socket receives are disallowed 1792 SEND = SD_SEND, /// socket sends are disallowed 1793 BOTH = SD_BOTH, /// both RECEIVE and SEND 1794 } 1795 1796 1797 /// Socket flags that may be OR'ed together: 1798 enum SocketFlags: int 1799 { 1800 NONE = 0, /// no flags specified 1801 1802 OOB = MSG_OOB, /// out-of-band stream data 1803 PEEK = MSG_PEEK, /// peek at incoming data without removing it from the queue, only for receiving 1804 DONTROUTE = MSG_DONTROUTE, /// data should not be subject to routing; this flag may be ignored. Only for sending 1805 } 1806 1807 import core.stdc.time:time_t; 1808 1809 struct timeval 1810 { 1811 time_t tv_sec; 1812 long tv_usec; 1813 } 1814 1815 1816 // /// Duration timeout value. 1817 struct TimeVal 1818 { 1819 timeval ctimeval; 1820 alias tv_sec_t = typeof(ctimeval.tv_sec); 1821 alias tv_usec_t = typeof(ctimeval.tv_usec); 1822 1823 /// Number of _seconds. 1824 pure nothrow @nogc @property 1825 ref inout(tv_sec_t) seconds() inout return 1826 { 1827 return ctimeval.tv_sec; 1828 } 1829 1830 /// Number of additional _microseconds. 1831 pure nothrow @nogc @property 1832 ref inout(tv_usec_t) microseconds() inout return 1833 { 1834 return ctimeval.tv_usec; 1835 } 1836 } 1837 1838 1839 /** 1840 * A collection of sockets for use with `Socket.select`. 1841 * 1842 * `SocketSet` wraps the platform `fd_set` type. However, unlike 1843 * `fd_set`, `SocketSet` is not statically limited to `FD_SETSIZE` 1844 * or any other limit, and grows as needed. 1845 */ 1846 class SocketSet 1847 { 1848 private: 1849 version (Windows) 1850 { 1851 // On Windows, fd_set is an array of socket handles, 1852 // following a word containing the fd_set instance size. 1853 // We use one dynamic array for everything, and use its first 1854 // element(s) for the count. 1855 1856 alias fd_set_count_type = typeof(fd_set.init.fd_count); 1857 alias fd_set_type = typeof(fd_set.init.fd_array[0]); 1858 static assert(fd_set_type.sizeof == socket_t.sizeof); 1859 1860 // Number of fd_set_type elements at the start of our array that are 1861 // used for the socket count and alignment 1862 1863 enum FD_SET_OFFSET = fd_set.fd_array.offsetof / fd_set_type.sizeof; 1864 static assert(FD_SET_OFFSET); 1865 static assert(fd_set.fd_count.offsetof % fd_set_type.sizeof == 0); 1866 1867 fd_set_type[] set; 1868 1869 void resize(size_t size) pure nothrow 1870 { 1871 set.length = FD_SET_OFFSET + size; 1872 } 1873 1874 ref inout(fd_set_count_type) count() @trusted @property inout pure nothrow @nogc 1875 { 1876 assert(set.length); 1877 return *cast(inout(fd_set_count_type)*)set.ptr; 1878 } 1879 1880 size_t capacity() @property const pure nothrow @nogc 1881 { 1882 return set.length - FD_SET_OFFSET; 1883 } 1884 1885 inout(socket_t)[] fds() @trusted inout @property pure nothrow @nogc 1886 { 1887 return cast(inout(socket_t)[])set[FD_SET_OFFSET .. FD_SET_OFFSET+count]; 1888 } 1889 } 1890 else 1891 version (LinuxLike) 1892 { 1893 // On Posix, fd_set is a bit array. We assume that the fd_set 1894 // type (declared in core.sys.posix.sys.select) is a structure 1895 // containing a single field, a static array. 1896 1897 static assert(fd_set.tupleof.length == 1); 1898 1899 // This is the type used in the fd_set array. 1900 // Using the type of the correct size is important for big-endian 1901 // architectures. 1902 1903 alias fd_set_type = typeof(fd_set.init.tupleof[0][0]); 1904 1905 // Number of file descriptors represented by one fd_set_type 1906 1907 enum FD_NFDBITS = 8 * fd_set_type.sizeof; 1908 1909 static fd_set_type mask(uint n) pure nothrow @nogc 1910 { 1911 return (cast(fd_set_type) 1) << (n % FD_NFDBITS); 1912 } 1913 1914 // Array size to fit that many sockets 1915 1916 static size_t lengthFor(size_t size) pure nothrow @nogc 1917 { 1918 return (size + (FD_NFDBITS-1)) / FD_NFDBITS; 1919 } 1920 1921 fd_set_type[] set; 1922 1923 void resize(size_t size) pure nothrow 1924 { 1925 set.length = lengthFor(size); 1926 } 1927 1928 // Make sure we can fit that many sockets 1929 1930 void setMinCapacity(size_t size) pure nothrow 1931 { 1932 auto length = lengthFor(size); 1933 if (set.length < length) 1934 set.length = length; 1935 } 1936 1937 size_t capacity() @property const pure nothrow @nogc 1938 { 1939 return set.length * FD_NFDBITS; 1940 } 1941 1942 int maxfd; 1943 } 1944 else 1945 static assert(false, "Unknown platform"); 1946 1947 public: 1948 1949 /** 1950 * Create a SocketSet with a specific initial capacity (defaults to 1951 * `FD_SETSIZE`, the system's default capacity). 1952 */ 1953 this(size_t size = FD_SETSIZE) pure nothrow 1954 { 1955 resize(size); 1956 reset(); 1957 } 1958 1959 /// Reset the `SocketSet` so that there are 0 `Socket`s in the collection. 1960 void reset() pure nothrow @nogc 1961 { 1962 version (Windows) 1963 count = 0; 1964 else 1965 { 1966 set[] = 0; 1967 maxfd = -1; 1968 } 1969 } 1970 1971 1972 void add(socket_t s) @trusted pure nothrow 1973 { 1974 version (Windows) 1975 { 1976 if (count == capacity) 1977 { 1978 set.length *= 2; 1979 set.length = set.capacity; 1980 } 1981 ++count; 1982 fds[$-1] = s; 1983 } 1984 else 1985 { 1986 auto index = s / FD_NFDBITS; 1987 auto length = set.length; 1988 if (index >= length) 1989 { 1990 while (index >= length) 1991 length *= 2; 1992 set.length = length; 1993 // set.length = set.capacity; 1994 } 1995 set[index] |= mask(s); 1996 if (maxfd < s) 1997 maxfd = s; 1998 } 1999 } 2000 2001 /** 2002 * Add a `Socket` to the collection. 2003 * The socket must not already be in the collection. 2004 */ 2005 void add(Socket s) pure nothrow 2006 { 2007 add(s.sock); 2008 } 2009 2010 void remove(socket_t s) pure nothrow 2011 { 2012 version (Windows) 2013 { 2014 import std.algorithm.searching : countUntil; 2015 auto fds = fds; 2016 auto p = fds.countUntil(s); 2017 if (p >= 0) 2018 fds[p] = fds[--count]; 2019 } 2020 else 2021 { 2022 auto index = s / FD_NFDBITS; 2023 if (index >= set.length) 2024 return; 2025 set[index] &= ~mask(s); 2026 // note: adjusting maxfd would require scanning the set, not worth it 2027 } 2028 } 2029 2030 2031 /** 2032 * Remove this `Socket` from the collection. 2033 * Does nothing if the socket is not in the collection already. 2034 */ 2035 void remove(Socket s) pure nothrow 2036 { 2037 remove(s.sock); 2038 } 2039 2040 int isSet(socket_t s) const pure nothrow @nogc 2041 { 2042 version (Windows) 2043 { 2044 import std.algorithm.searching : canFind; 2045 return fds.canFind(s) ? 1 : 0; 2046 } 2047 else 2048 { 2049 if (s > maxfd) 2050 return 0; 2051 auto index = s / FD_NFDBITS; 2052 return (set[index] & mask(s)) ? 1 : 0; 2053 } 2054 } 2055 2056 2057 /// Return nonzero if this `Socket` is in the collection. 2058 int isSet(Socket s) const pure nothrow @nogc 2059 { 2060 return isSet(s.sock); 2061 } 2062 2063 2064 /** 2065 * Returns: 2066 * The current capacity of this `SocketSet`. The exact 2067 * meaning of the return value varies from platform to platform. 2068 * 2069 * Note: 2070 * Since D 2.065, this value does not indicate a 2071 * restriction, and `SocketSet` will grow its capacity as 2072 * needed automatically. 2073 */ 2074 @property uint max() const pure nothrow @nogc 2075 { 2076 return cast(uint) capacity; 2077 } 2078 2079 2080 fd_set* toFd_set() @trusted pure nothrow @nogc 2081 { 2082 return cast(fd_set*) set.ptr; 2083 } 2084 2085 2086 int selectn() const pure nothrow @nogc 2087 { 2088 version (Windows) 2089 { 2090 return count; 2091 } 2092 else version (LinuxLike) 2093 { 2094 return maxfd + 1; 2095 } 2096 } 2097 } 2098 2099 /// The level at which a socket option is defined: 2100 enum SocketOptionLevel: int 2101 { 2102 SOCKET = SOL_SOCKET, /// Socket level 2103 IP = ProtocolType.IP, /// Internet Protocol version 4 level 2104 ICMP = ProtocolType.ICMP, /// Internet Control Message Protocol level 2105 IGMP = ProtocolType.IGMP, /// Internet Group Management Protocol level 2106 GGP = ProtocolType.GGP, /// Gateway to Gateway Protocol level 2107 TCP = ProtocolType.TCP, /// Transmission Control Protocol level 2108 PUP = ProtocolType.PUP, /// PARC Universal Packet Protocol level 2109 UDP = ProtocolType.UDP, /// User Datagram Protocol level 2110 IDP = ProtocolType.IDP, /// Xerox NS protocol level 2111 RAW = ProtocolType.RAW, /// Raw IP packet level 2112 IPV6 = ProtocolType.IPV6, /// Internet Protocol version 6 level 2113 } 2114 2115 /// _Linger information for use with SocketOption.LINGER. 2116 // struct Linger 2117 // { 2118 // _clinger clinger; 2119 2120 // private alias l_onoff_t = typeof(_clinger.init.l_onoff ); 2121 // private alias l_linger_t = typeof(_clinger.init.l_linger); 2122 2123 // /// Nonzero for _on. 2124 // pure nothrow @nogc @property 2125 // ref inout(l_onoff_t) on() inout return 2126 // { 2127 // return clinger.l_onoff; 2128 // } 2129 2130 // /// Linger _time. 2131 // pure nothrow @nogc @property 2132 // ref inout(l_linger_t) time() inout return 2133 // { 2134 // return clinger.l_linger; 2135 // } 2136 // } 2137 2138 /// Specifies a socket option: 2139 enum SocketOption: int 2140 { 2141 DEBUG = SO_DEBUG, /// Record debugging information 2142 BROADCAST = SO_BROADCAST, /// Allow transmission of broadcast messages 2143 REUSEADDR = SO_REUSEADDR, /// Allow local reuse of address 2144 LINGER = SO_LINGER, /// Linger on close if unsent data is present 2145 OOBINLINE = SO_OOBINLINE, /// Receive out-of-band data in band 2146 SNDBUF = SO_SNDBUF, /// Send buffer size 2147 RCVBUF = SO_RCVBUF, /// Receive buffer size 2148 DONTROUTE = SO_DONTROUTE, /// Do not route 2149 SNDTIMEO = SO_SNDTIMEO, /// Send timeout 2150 RCVTIMEO = SO_RCVTIMEO, /// Receive timeout 2151 ERROR = SO_ERROR, /// Retrieve and clear error status 2152 KEEPALIVE = SO_KEEPALIVE, /// Enable keep-alive packets 2153 ACCEPTCONN = SO_ACCEPTCONN, /// Listen 2154 RCVLOWAT = SO_RCVLOWAT, /// Minimum number of input bytes to process 2155 SNDLOWAT = SO_SNDLOWAT, /// Minimum number of output bytes to process 2156 TYPE = SO_TYPE, /// Socket type 2157 2158 // SocketOptionLevel.TCP: 2159 TCP_NODELAY = .TCP_NODELAY, /// Disable the Nagle algorithm for send coalescing 2160 2161 // SocketOptionLevel.IPV6: 2162 IPV6_UNICAST_HOPS = .IPV6_UNICAST_HOPS, /// IP unicast hop limit 2163 IPV6_MULTICAST_IF = .IPV6_MULTICAST_IF, /// IP multicast interface 2164 IPV6_MULTICAST_LOOP = .IPV6_MULTICAST_LOOP, /// IP multicast loopback 2165 IPV6_MULTICAST_HOPS = .IPV6_MULTICAST_HOPS, /// IP multicast hops 2166 IPV6_JOIN_GROUP = .IPV6_JOIN_GROUP, /// Add an IP group membership 2167 IPV6_LEAVE_GROUP = .IPV6_LEAVE_GROUP, /// Drop an IP group membership 2168 IPV6_V6ONLY = .IPV6_V6ONLY, /// Treat wildcard bind as AF_INET6-only 2169 } 2170 2171 2172 /** 2173 * Class that creates a network communication endpoint using 2174 * the Berkeley sockets interface. 2175 */ 2176 class Socket 2177 { 2178 private: 2179 socket_t sock; 2180 AddressFamily _family; 2181 2182 version (Windows) 2183 bool _blocking = true; /// Property to get or set whether the socket is blocking or nonblocking. 2184 2185 // The WinSock timeouts seem to be effectively skewed by a constant 2186 // offset of about half a second (value in milliseconds). This has 2187 // been confirmed on updated (as of Jun 2011) Windows XP, Windows 7 2188 // and Windows Server 2008 R2 boxes. The unittest below tests this 2189 // behavior. 2190 enum WINSOCK_TIMEOUT_SKEW = 500; 2191 2192 void setSock(socket_t handle) 2193 { 2194 assert(handle != socket_t.init); 2195 sock = handle; 2196 2197 // Set the option to disable SIGPIPE on send() if the platform 2198 // has it (e.g. on OS X). 2199 static if (is(typeof(SO_NOSIGPIPE))) 2200 { 2201 setOption(SocketOptionLevel.SOCKET, cast(SocketOption) SO_NOSIGPIPE, true); 2202 } 2203 } 2204 2205 2206 // For use with accepting(). 2207 protected this() pure nothrow @nogc 2208 { 2209 } 2210 2211 2212 public: 2213 2214 /** 2215 * Create a blocking socket. If a single protocol type exists to support 2216 * this socket type within the address family, the `ProtocolType` may be 2217 * omitted. 2218 */ 2219 this(AddressFamily af, SocketType type, ProtocolType protocol) @trusted 2220 { 2221 _family = af; 2222 auto handle = cast(socket_t) socket(af, type, protocol); 2223 if (handle == socket_t.init) 2224 throw new SocketOSException("Unable to create socket"); 2225 setSock(handle); 2226 } 2227 2228 /// ditto 2229 this(AddressFamily af, SocketType type) 2230 { 2231 /* A single protocol exists to support this socket type within the 2232 * protocol family, so the ProtocolType is assumed. 2233 */ 2234 this(af, type, cast(ProtocolType) 0); // Pseudo protocol number. 2235 } 2236 2237 2238 /// ditto 2239 this(AddressFamily af, SocketType type, scope const(char)[] protocolName) @trusted 2240 { 2241 protoent* proto; 2242 proto = getprotobyname(protocolName.tempCString()); 2243 if (!proto) 2244 throw new SocketOSException("Unable to find the protocol"); 2245 this(af, type, cast(ProtocolType) proto.p_proto); 2246 } 2247 2248 2249 /** 2250 * Create a blocking socket using the parameters from the specified 2251 * `AddressInfo` structure. 2252 */ 2253 this(const scope AddressInfo info) 2254 { 2255 this(info.family, info.type, info.protocol); 2256 } 2257 2258 /// Use an existing socket handle. 2259 this(socket_t sock, AddressFamily af) pure nothrow @nogc 2260 { 2261 assert(sock != socket_t.init); 2262 this.sock = sock; 2263 this._family = af; 2264 } 2265 2266 2267 ~this() nothrow @nogc 2268 { 2269 close(); 2270 } 2271 2272 2273 /// Get underlying socket handle. 2274 @property socket_t handle() const pure nothrow @nogc 2275 { 2276 return sock; 2277 } 2278 2279 /** 2280 * Releases the underlying socket handle from the Socket object. Once it 2281 * is released, you cannot use the Socket object's methods anymore. This 2282 * also means the Socket destructor will no longer close the socket - it 2283 * becomes your responsibility. 2284 * 2285 * To get the handle without releasing it, use the `handle` property. 2286 */ 2287 @property socket_t release() pure nothrow @nogc 2288 { 2289 auto h = sock; 2290 this.sock = socket_t.init; 2291 return h; 2292 } 2293 2294 /** 2295 * Get/set socket's blocking flag. 2296 * 2297 * When a socket is blocking, calls to receive(), accept(), and send() 2298 * will block and wait for data/action. 2299 * A non-blocking socket will immediately return instead of blocking. 2300 */ 2301 @property bool blocking() @trusted const nothrow @nogc 2302 { 2303 version (Windows) 2304 { 2305 return _blocking; 2306 } 2307 else version (LinuxLike) 2308 { 2309 return !(fcntl(handle, F_GETFL, 0) & O_NONBLOCK); 2310 } 2311 } 2312 2313 /// ditto 2314 @property void blocking(bool byes) @trusted 2315 { 2316 version (Windows) 2317 { 2318 uint num = !byes; 2319 if (_SOCKET_ERROR == ioctlsocket(sock, FIONBIO, &num)) 2320 goto err; 2321 _blocking = byes; 2322 } 2323 else version (LinuxLike) 2324 { 2325 int x = fcntl(sock, F_GETFL, 0); 2326 if (-1 == x) 2327 goto err; 2328 if (byes) 2329 x &= ~O_NONBLOCK; 2330 else 2331 x |= O_NONBLOCK; 2332 if (-1 == fcntl(sock, F_SETFL, x)) 2333 goto err; 2334 } 2335 return; // Success. 2336 2337 err: 2338 throw new SocketOSException("Unable to set socket blocking"); 2339 } 2340 2341 2342 /// Get the socket's address family. 2343 @property AddressFamily addressFamily() 2344 { 2345 return _family; 2346 } 2347 2348 /// Property that indicates if this is a valid, alive socket. 2349 @property bool isAlive() @trusted const 2350 { 2351 int type; 2352 socklen_t typesize = cast(socklen_t) type.sizeof; 2353 return !getsockopt(sock, SOL_SOCKET, SO_TYPE, cast(char*)&type, &typesize); 2354 } 2355 2356 /** 2357 * Associate a local address with this socket. 2358 * 2359 * Params: 2360 * addr = The $(LREF Address) to associate this socket with. 2361 * 2362 * Throws: $(LREF SocketOSException) when unable to bind the socket. 2363 */ 2364 void bind(Address addr) @trusted 2365 { 2366 if (_SOCKET_ERROR == .bind(sock, addr.name, addr.nameLen)) 2367 throw new SocketOSException("Unable to bind socket"); 2368 } 2369 2370 /** 2371 * Establish a connection. If the socket is blocking, connect waits for 2372 * the connection to be made. If the socket is nonblocking, connect 2373 * returns immediately and the connection attempt is still in progress. 2374 */ 2375 void connect(Address to) @trusted 2376 { 2377 if (_SOCKET_ERROR == .connect(sock, to.name, to.nameLen)) 2378 { 2379 int err; 2380 err = _lasterr(); 2381 2382 if (!blocking) 2383 { 2384 version (Windows) 2385 { 2386 if (WSAEWOULDBLOCK == err) 2387 return; 2388 } 2389 else version (LinuxLike) 2390 { 2391 if (EINPROGRESS == err) 2392 return; 2393 } 2394 else 2395 { 2396 static assert(0); 2397 } 2398 } 2399 throw new SocketOSException("Unable to connect socket", err); 2400 } 2401 } 2402 2403 /** 2404 * Listen for an incoming connection. `bind` must be called before you 2405 * can `listen`. The `backlog` is a request of how many pending 2406 * incoming connections are queued until `accept`ed. 2407 */ 2408 void listen(int backlog) @trusted 2409 { 2410 if (_SOCKET_ERROR == .listen(sock, backlog)) 2411 throw new SocketOSException("Unable to listen on socket"); 2412 } 2413 2414 /** 2415 * Called by `accept` when a new `Socket` must be created for a new 2416 * connection. To use a derived class, override this method and return an 2417 * instance of your class. The returned `Socket`'s handle must not be 2418 * set; `Socket` has a protected constructor `this()` to use in this 2419 * situation. 2420 * 2421 * Override to use a derived class. 2422 * The returned socket's handle must not be set. 2423 */ 2424 protected Socket accepting() pure nothrow 2425 { 2426 return new Socket; 2427 } 2428 2429 /** 2430 * Accept an incoming connection. If the socket is blocking, `accept` 2431 * waits for a connection request. Throws `SocketAcceptException` if 2432 * unable to _accept. See `accepting` for use with derived classes. 2433 */ 2434 Socket accept() @trusted 2435 { 2436 auto newsock = cast(socket_t).accept(sock, null, null); 2437 if (socket_t.init == newsock) 2438 return null; 2439 2440 Socket newSocket; 2441 try 2442 { 2443 newSocket = accepting(); 2444 assert(newSocket.sock == socket_t.init); 2445 2446 newSocket.setSock(newsock); 2447 version (Windows) 2448 newSocket._blocking = _blocking; //inherits blocking mode 2449 newSocket._family = _family; //same family 2450 } 2451 catch (Throwable o) 2452 { 2453 _close(newsock); 2454 throw o; 2455 } 2456 2457 return newSocket; 2458 } 2459 2460 /// Disables sends and/or receives. 2461 void shutdown(SocketShutdown how) @trusted nothrow @nogc 2462 { 2463 .shutdown(sock, cast(int) how); 2464 } 2465 2466 2467 private static void _close(socket_t sock) @system nothrow @nogc 2468 { 2469 version (Windows) 2470 { 2471 .closesocket(sock); 2472 } 2473 else version (LinuxLike) 2474 { 2475 .close(sock); 2476 } 2477 } 2478 2479 2480 /** 2481 * Immediately drop any connections and release socket resources. 2482 * The `Socket` object is no longer usable after `close`. 2483 * Calling `shutdown` before `close` is recommended 2484 * for connection-oriented sockets. 2485 */ 2486 void close() scope @trusted nothrow @nogc 2487 { 2488 _close(sock); 2489 sock = socket_t.init; 2490 } 2491 2492 2493 /** 2494 * Returns: The local machine's host name 2495 */ 2496 static @property string hostName() @trusted // getter 2497 { 2498 char[256] result; // Host names are limited to 255 chars. 2499 if (_SOCKET_ERROR == .gethostname(result.ptr, result.length)) 2500 throw new SocketOSException("Unable to obtain host name"); 2501 return to!string(result.ptr); 2502 } 2503 2504 /// Remote endpoint `Address`. 2505 @property Address remoteAddress() @trusted 2506 { 2507 Address addr = createAddress(); 2508 socklen_t nameLen = addr.nameLen; 2509 if (_SOCKET_ERROR == .getpeername(sock, addr.name, &nameLen)) 2510 throw new SocketOSException("Unable to obtain remote socket address"); 2511 addr.setNameLen(nameLen); 2512 assert(addr.addressFamily == _family); 2513 return addr; 2514 } 2515 2516 /// Local endpoint `Address`. 2517 @property Address localAddress() @trusted 2518 { 2519 Address addr = createAddress(); 2520 socklen_t nameLen = addr.nameLen; 2521 if (_SOCKET_ERROR == .getsockname(sock, addr.name, &nameLen)) 2522 throw new SocketOSException("Unable to obtain local socket address"); 2523 addr.setNameLen(nameLen); 2524 assert(addr.addressFamily == _family); 2525 return addr; 2526 } 2527 2528 /** 2529 * Send or receive error code. See `wouldHaveBlocked`, 2530 * `lastSocketError` and `Socket.getErrorText` for obtaining more 2531 * information about the error. 2532 */ 2533 enum int ERROR = _SOCKET_ERROR; 2534 2535 private static int capToInt(size_t size) nothrow @nogc 2536 { 2537 // Windows uses int instead of size_t for length arguments. 2538 // Luckily, the send/recv functions make no guarantee that 2539 // all the data is sent, so we use that to send at most 2540 // int.max bytes. 2541 return size > size_t(int.max) ? int.max : cast(int) size; 2542 } 2543 2544 /** 2545 * Send data on the connection. If the socket is blocking and there is no 2546 * buffer space left, `send` waits. 2547 * Returns: The number of bytes actually sent, or `Socket.ERROR` on 2548 * failure. 2549 */ 2550 ptrdiff_t send(scope const(void)[] buf, SocketFlags flags) @trusted 2551 { 2552 static if (is(typeof(MSG_NOSIGNAL))) 2553 { 2554 flags = cast(SocketFlags)(flags | MSG_NOSIGNAL); 2555 } 2556 version (Windows) 2557 auto sent = .send(sock, buf.ptr, capToInt(buf.length), cast(int) flags); 2558 else 2559 auto sent = .send(sock, buf.ptr, buf.length, cast(int) flags); 2560 return sent; 2561 } 2562 2563 /// ditto 2564 ptrdiff_t send(scope const(void)[] buf) 2565 { 2566 return send(buf, SocketFlags.NONE); 2567 } 2568 2569 /** 2570 * Send data to a specific destination Address. If the destination address is 2571 * not specified, a connection must have been made and that address is used. 2572 * If the socket is blocking and there is no buffer space left, `sendTo` waits. 2573 * Returns: The number of bytes actually sent, or `Socket.ERROR` on 2574 * failure. 2575 */ 2576 ptrdiff_t sendTo(scope const(void)[] buf, SocketFlags flags, Address to) @trusted 2577 { 2578 static if (is(typeof(MSG_NOSIGNAL))) 2579 { 2580 flags = cast(SocketFlags)(flags | MSG_NOSIGNAL); 2581 } 2582 version (Windows) 2583 return .sendto( 2584 sock, buf.ptr, capToInt(buf.length), 2585 cast(int) flags, to.name, to.nameLen 2586 ); 2587 else 2588 return .sendto(sock, buf.ptr, buf.length, cast(int) flags, to.name, to.nameLen); 2589 } 2590 2591 /// ditto 2592 ptrdiff_t sendTo(scope const(void)[] buf, Address to) 2593 { 2594 return sendTo(buf, SocketFlags.NONE, to); 2595 } 2596 2597 2598 //assumes you connect()ed 2599 /// ditto 2600 ptrdiff_t sendTo(scope const(void)[] buf, SocketFlags flags) @trusted 2601 { 2602 static if (is(typeof(MSG_NOSIGNAL))) 2603 { 2604 flags = cast(SocketFlags)(flags | MSG_NOSIGNAL); 2605 } 2606 version (Windows) 2607 return .sendto(sock, buf.ptr, capToInt(buf.length), cast(int) flags, null, 0); 2608 else 2609 return .sendto(sock, buf.ptr, buf.length, cast(int) flags, null, 0); 2610 } 2611 2612 2613 //assumes you connect()ed 2614 /// ditto 2615 ptrdiff_t sendTo(scope const(void)[] buf) 2616 { 2617 return sendTo(buf, SocketFlags.NONE); 2618 } 2619 2620 2621 /** 2622 * Receive data on the connection. If the socket is blocking, `receive` 2623 * waits until there is data to be received. 2624 * Returns: The number of bytes actually received, `0` if the remote side 2625 * has closed the connection, or `Socket.ERROR` on failure. 2626 */ 2627 ptrdiff_t receive(scope void[] buf, SocketFlags flags) @trusted 2628 { 2629 version (Windows) // Does not use size_t 2630 { 2631 return buf.length 2632 ? .recv(sock, buf.ptr, capToInt(buf.length), cast(int) flags) 2633 : 0; 2634 } 2635 else 2636 { 2637 return buf.length 2638 ? .recv(sock, buf.ptr, buf.length, cast(int) flags) 2639 : 0; 2640 } 2641 } 2642 2643 /// ditto 2644 ptrdiff_t receive(scope void[] buf) 2645 { 2646 return receive(buf, SocketFlags.NONE); 2647 } 2648 2649 /** 2650 * Receive data and get the remote endpoint `Address`. 2651 * If the socket is blocking, `receiveFrom` waits until there is data to 2652 * be received. 2653 * Returns: The number of bytes actually received, `0` if the remote side 2654 * has closed the connection, or `Socket.ERROR` on failure. 2655 */ 2656 ptrdiff_t receiveFrom(scope void[] buf, SocketFlags flags, ref Address from) @trusted 2657 { 2658 if (!buf.length) //return 0 and don't think the connection closed 2659 return 0; 2660 if (from is null || from.addressFamily != _family) 2661 from = createAddress(); 2662 socklen_t nameLen = from.nameLen; 2663 version (Windows) 2664 auto read = .recvfrom(sock, buf.ptr, capToInt(buf.length), cast(int) flags, from.name, &nameLen); 2665 2666 else 2667 auto read = .recvfrom(sock, buf.ptr, buf.length, cast(int) flags, from.name, &nameLen); 2668 2669 if (read >= 0) 2670 { 2671 from.setNameLen(nameLen); 2672 assert(from.addressFamily == _family); 2673 } 2674 return read; 2675 } 2676 2677 2678 /// ditto 2679 ptrdiff_t receiveFrom(scope void[] buf, ref Address from) 2680 { 2681 return receiveFrom(buf, SocketFlags.NONE, from); 2682 } 2683 2684 2685 //assumes you connect()ed 2686 /// ditto 2687 ptrdiff_t receiveFrom(scope void[] buf, SocketFlags flags) @trusted 2688 { 2689 if (!buf.length) //return 0 and don't think the connection closed 2690 return 0; 2691 version (Windows) 2692 { 2693 auto read = .recvfrom(sock, buf.ptr, capToInt(buf.length), cast(int) flags, null, null); 2694 // if (!read) //connection closed 2695 return read; 2696 } 2697 else 2698 { 2699 auto read = .recvfrom(sock, buf.ptr, buf.length, cast(int) flags, null, null); 2700 // if (!read) //connection closed 2701 return read; 2702 } 2703 } 2704 2705 2706 //assumes you connect()ed 2707 /// ditto 2708 ptrdiff_t receiveFrom(scope void[] buf) 2709 { 2710 return receiveFrom(buf, SocketFlags.NONE); 2711 } 2712 2713 2714 /** 2715 * Get a socket option. 2716 * Returns: The number of bytes written to `result`. 2717 * The length, in bytes, of the actual result - very different from getsockopt() 2718 */ 2719 int getOption(SocketOptionLevel level, SocketOption option, scope void[] result) @trusted 2720 { 2721 socklen_t len = cast(socklen_t) result.length; 2722 if (_SOCKET_ERROR == .getsockopt(sock, cast(int) level, cast(int) option, result.ptr, &len)) 2723 throw new SocketOSException("Unable to get socket option"); 2724 return len; 2725 } 2726 2727 2728 /// Common case of getting integer and boolean options. 2729 int getOption(SocketOptionLevel level, SocketOption option, out int32_t result) @trusted 2730 { 2731 return getOption(level, option, (&result)[0 .. 1]); 2732 } 2733 2734 2735 /// Get the linger option. 2736 // int getOption(SocketOptionLevel level, SocketOption option, out Linger result) @trusted 2737 // { 2738 // //return getOption(cast(SocketOptionLevel) SocketOptionLevel.SOCKET, SocketOption.LINGER, (&result)[0 .. 1]); 2739 // return getOption(level, option, (&result.clinger)[0 .. 1]); 2740 // } 2741 2742 /// Set a socket option. 2743 void setOption(SocketOptionLevel level, SocketOption option, scope void[] value) @trusted 2744 { 2745 if (_SOCKET_ERROR == .setsockopt(sock, cast(int) level, 2746 cast(int) option, value.ptr, cast(uint) value.length)) 2747 throw new SocketOSException("Unable to set socket option"); 2748 } 2749 2750 2751 /// Common case for setting integer and boolean options. 2752 void setOption(SocketOptionLevel level, SocketOption option, int32_t value) @trusted 2753 { 2754 setOption(level, option, (&value)[0 .. 1]); 2755 } 2756 2757 2758 /// Set the linger option. 2759 // void setOption(SocketOptionLevel level, SocketOption option, Linger value) @trusted 2760 // { 2761 // //setOption(cast(SocketOptionLevel) SocketOptionLevel.SOCKET, SocketOption.LINGER, (&value)[0 .. 1]); 2762 // setOption(level, option, (&value.clinger)[0 .. 1]); 2763 // } 2764 /** 2765 * Get a text description of this socket's error status, and clear the 2766 * socket's error status. 2767 */ 2768 string getErrorText() 2769 { 2770 int32_t error; 2771 getOption(SocketOptionLevel.SOCKET, SocketOption.ERROR, error); 2772 return formatSocketError(error); 2773 } 2774 2775 /** 2776 * Enables TCP keep-alive with the specified parameters. 2777 * 2778 * Params: 2779 * time = Number of seconds with no activity until the first 2780 * keep-alive packet is sent. 2781 * interval = Number of seconds between when successive keep-alive 2782 * packets are sent if no acknowledgement is received. 2783 * 2784 * Throws: `SocketOSException` if setting the options fails, or 2785 * `SocketFeatureException` if setting keep-alive parameters is 2786 * unsupported on the current platform. 2787 */ 2788 void setKeepAlive(int time, int interval) @trusted 2789 { 2790 version (Windows) 2791 { 2792 tcp_keepalive options; 2793 options.onoff = 1; 2794 options.keepalivetime = time * 1000; 2795 options.keepaliveinterval = interval * 1000; 2796 uint cbBytesReturned; 2797 enforce(WSAIoctl(sock, SIO_KEEPALIVE_VALS, 2798 &options, options.sizeof, 2799 null, 0, 2800 &cbBytesReturned, null, null) == 0, 2801 new SocketOSException("Error setting keep-alive")); 2802 } 2803 else 2804 static if (is(typeof(TCP_KEEPIDLE)) && is(typeof(TCP_KEEPINTVL))) 2805 { 2806 setOption(SocketOptionLevel.TCP, cast(SocketOption) TCP_KEEPIDLE, time); 2807 setOption(SocketOptionLevel.TCP, cast(SocketOption) TCP_KEEPINTVL, interval); 2808 setOption(SocketOptionLevel.SOCKET, SocketOption.KEEPALIVE, true); 2809 } 2810 else 2811 throw new SocketFeatureException("Setting keep-alive options " ~ 2812 "is not supported on this platform"); 2813 } 2814 2815 // /// ditto 2816 // //maximum timeout 2817 static int select(SocketSet checkRead, SocketSet checkWrite, SocketSet checkError) 2818 { 2819 return select(checkRead, checkWrite, checkError, null); 2820 } 2821 2822 /// Ditto 2823 static int select(SocketSet checkRead, SocketSet checkWrite, SocketSet checkError, TimeVal* timeout) @trusted 2824 in 2825 { 2826 //make sure none of the SocketSet's are the same object 2827 if (checkRead) 2828 { 2829 assert(checkRead !is checkWrite); 2830 assert(checkRead !is checkError); 2831 } 2832 if (checkWrite) 2833 { 2834 assert(checkWrite !is checkError); 2835 } 2836 } 2837 do 2838 { 2839 fd_set* fr, fw, fe; 2840 int n = 0; 2841 2842 version (Windows) 2843 { 2844 // Windows has a problem with empty fd_set`s that aren't null. 2845 fr = checkRead && checkRead.count ? checkRead.toFd_set() : null; 2846 fw = checkWrite && checkWrite.count ? checkWrite.toFd_set() : null; 2847 fe = checkError && checkError.count ? checkError.toFd_set() : null; 2848 } 2849 else 2850 { 2851 if (checkRead) 2852 { 2853 fr = checkRead.toFd_set(); 2854 n = checkRead.selectn(); 2855 } 2856 else 2857 { 2858 fr = null; 2859 } 2860 2861 if (checkWrite) 2862 { 2863 fw = checkWrite.toFd_set(); 2864 int _n; 2865 _n = checkWrite.selectn(); 2866 if (_n > n) 2867 n = _n; 2868 } 2869 else 2870 { 2871 fw = null; 2872 } 2873 2874 if (checkError) 2875 { 2876 fe = checkError.toFd_set(); 2877 int _n; 2878 _n = checkError.selectn(); 2879 if (_n > n) 2880 n = _n; 2881 } 2882 else 2883 { 2884 fe = null; 2885 } 2886 2887 // Make sure the sets' capacity matches, to avoid select reading 2888 // out of bounds just because one set was bigger than another 2889 if (checkRead ) checkRead .setMinCapacity(n); 2890 if (checkWrite) checkWrite.setMinCapacity(n); 2891 if (checkError) checkError.setMinCapacity(n); 2892 } 2893 2894 int result = .select(n, fr, fw, fe, &timeout.ctimeval); 2895 2896 version (Windows) 2897 { 2898 if (_SOCKET_ERROR == result && WSAGetLastError() == WSAEINTR) 2899 return -1; 2900 } 2901 else version (LinuxLike) 2902 { 2903 if (_SOCKET_ERROR == result && errno == EINTR) 2904 return -1; 2905 } 2906 else 2907 { 2908 static assert(0); 2909 } 2910 2911 if (_SOCKET_ERROR == result) 2912 throw new SocketOSException("Socket select error"); 2913 2914 return result; 2915 } 2916 2917 2918 /** 2919 * Can be overridden to support other addresses. 2920 * Returns: A new `Address` object for the current address family. 2921 */ 2922 protected Address createAddress() pure nothrow 2923 { 2924 Address result; 2925 switch (_family) 2926 { 2927 static if (is(sockaddr_un)) 2928 { 2929 case AddressFamily.UNIX: 2930 result = new UnixAddress; 2931 break; 2932 } 2933 2934 case AddressFamily.INET: 2935 result = new InternetAddress; 2936 break; 2937 2938 case AddressFamily.INET6: 2939 result = new Internet6Address; 2940 break; 2941 2942 default: 2943 result = new UnknownAddress; 2944 } 2945 return result; 2946 } 2947 2948 } 2949 2950 2951 /// Shortcut class for a TCP Socket. 2952 class TcpSocket: Socket 2953 { 2954 /// Constructs a blocking TCP Socket. 2955 this(AddressFamily family) 2956 { 2957 super(family, SocketType.STREAM, ProtocolType.TCP); 2958 } 2959 2960 /// Constructs a blocking IPv4 TCP Socket. 2961 this() 2962 { 2963 this(AddressFamily.INET); 2964 } 2965 2966 2967 //shortcut 2968 /// Constructs a blocking TCP Socket and connects to the given `Address`. 2969 this(Address connectTo) 2970 { 2971 this(connectTo.addressFamily); 2972 connect(connectTo); 2973 } 2974 } 2975 2976 2977 /// Shortcut class for a UDP Socket. 2978 class UdpSocket: Socket 2979 { 2980 /// Constructs a blocking UDP Socket. 2981 this(AddressFamily family) 2982 { 2983 super(family, SocketType.DGRAM, ProtocolType.UDP); 2984 } 2985 2986 2987 /// Constructs a blocking IPv4 UDP Socket. 2988 this() 2989 { 2990 this(AddressFamily.INET); 2991 } 2992 } 2993 2994 2995 2996 /** 2997 * Creates a pair of connected sockets. 2998 * 2999 * The two sockets are indistinguishable. 3000 * 3001 * Throws: `SocketException` if creation of the sockets fails. 3002 */ 3003 Socket[2] socketPair() @trusted 3004 { 3005 version (LinuxLike) 3006 { 3007 int[2] socks; 3008 if (socketpair(AF_UNIX, SOCK_STREAM, 0, socks) == -1) 3009 throw new SocketOSException("Unable to create socket pair"); 3010 3011 Socket toSocket(size_t id) 3012 { 3013 auto s = new Socket; 3014 s.setSock(cast(socket_t) socks[id]); 3015 s._family = AddressFamily.UNIX; 3016 return s; 3017 } 3018 3019 return [toSocket(0), toSocket(1)]; 3020 } 3021 else version (Windows) 3022 { 3023 // We do not have socketpair() on Windows, just manually create a 3024 // pair of sockets connected over some localhost port. 3025 Socket[2] result; 3026 3027 auto listener = new TcpSocket(); 3028 listener.setOption(SocketOptionLevel.SOCKET, SocketOption.REUSEADDR, true); 3029 listener.bind(new InternetAddress(INADDR_LOOPBACK, InternetAddress.PORT_ANY)); 3030 auto addr = listener.localAddress; 3031 listener.listen(1); 3032 3033 result[0] = new TcpSocket(addr); 3034 result[1] = listener.accept(); 3035 3036 listener.close(); 3037 return result; 3038 } 3039 else 3040 static assert(false); 3041 } 3042 3043 ///